package com.lx.adapter;

import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.google.common.cache.Cache;
import com.lx.dto.*;
import com.lx.service.IWeixinApiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import retrofit2.Call;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

import javax.annotation.Resource;
import java.io.IOException;

@Slf4j
@Service
public class LoginAdapter implements ILoginAdapter {

    @Value("${weixin.config.app-id}")
    private String appid;
    @Value("${weixin.config.app-secret}")
    private String appSecret;
    @Value("${weixin.config.redirectUri}")
    private String redirectUri;
    @Value("${weixin.config.oauth2AuthorizeUrl}")
    private String oauth2AuthorizeUrl;
    @Resource
    private Cache<String, String> weixinAccessToken;
    @Resource
    private IWeixinApiService weixinApiService;

    @Override
    public String createQrCodeTicket() throws IOException {
        // 1. 获取 accessToken 【实际业务场景，按需处理下异常】
        String accessToken = weixinAccessToken.getIfPresent(appid);
        if (null == accessToken) {
            Call<WeixinTokenResponseDTO> call = weixinApiService.getToken("client_credential", appid, appSecret);
            WeixinTokenResponseDTO weixinTokenResponseDTO = call.execute().body();
            accessToken = weixinTokenResponseDTO.getAccess_token();
            weixinAccessToken.put(appid, accessToken);
            log.info("获取 accessToken appid:{} accessToken:{}", appid, accessToken);
        }
        // 2. 生成 ticket
        WeixinQrCodeRequestDTO request = WeixinQrCodeRequestDTO.builder()
                .expire_seconds(120) // 过期时间单位为秒 2592000 = 30天
                .action_name(WeixinQrCodeRequestDTO.ActionNameTypeVO.QR_SCENE.getCode())
                .action_info(WeixinQrCodeRequestDTO.ActionInfo.builder()
                        .scene(WeixinQrCodeRequestDTO.ActionInfo.Scene.builder()
                                .scene_id(100601) // 场景ID
                                .scene_str("test") //配合 ActionNameTypeVO.QR_STR_SCENE
                                .build())
                        .build())
                .build();

        Call<WeixinQrCodeResponseDTO> qrCodeCall = weixinApiService.createQrCode(accessToken, request);
        WeixinQrCodeResponseDTO weixinQrCodeResponseDTO = qrCodeCall.execute().body();
        return weixinQrCodeResponseDTO.getTicket();
    }

    @Override
    public String getAuthorizationCode() throws IOException {
        String qrCode = oauth2AuthorizeUrl
                .replace("APPID", appid)
                .replace("REDIRECT_URI", redirectUri)
                .replace("SCOPE", "snsapi_userinfo");
        QrConfig qrConfig = new QrConfig(200, 200);
        return QrCodeUtil.generateAsBase64(qrCode, qrConfig, "png");
    }

    @Override
    public void getUserInfo(String code) throws IOException {
        IWeixinApiService iWeixinApiService = new Retrofit.Builder()
                .baseUrl("https://api.weixin.qq.com/")
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(JacksonConverterFactory.create())
                .build()
                .create(IWeixinApiService.class);
        Call<OAuth2AuthorizationToken> authorizationedAccessToken = iWeixinApiService.authorizationAccessToken(appid, appSecret, code, "authorization_code");
        OAuth2AuthorizationToken body = authorizationedAccessToken.execute().body();
        if (body != null) {
            String openid = body.getOpenid();
            String accessToken = body.getAccess_token();
            weixinAccessToken.put(openid, accessToken);

            UserInfoResponseDTO userInfoResponseDTO = iWeixinApiService.getAuthorizationUserInfo(accessToken, openid, "zh_CN").execute().body();
            log.info("用户基本信息 :{}", userInfoResponseDTO.toString());
        }

    }

}
